module sync_fifo #(
    parameter DATA_WIDTH = 32,
    parameter DEPTH = 32
)(
    input clk,
    input reset,
    input wr_en,
    input rd_en,
    input [DATA_WIDTH-1:0] din,
    output reg [DATA_WIDTH-1:0] dout,
    output full,
    output reg empty
);

localparam PTR_WIDTH = $clog2(DEPTH);
reg [PTR_WIDTH:0] cnt;       // 计数器：0 ~ DEPTH
reg [DATA_WIDTH-1:0] mem[0:DEPTH-1];
reg [PTR_WIDTH-1:0] wr_ptr, rd_ptr;

always @(posedge clk) begin
    if (reset) begin
        wr_ptr <= '0;
        rd_ptr <= '0;
        cnt <= '0;
        dout <= '0;
         foreach (mem[i]) mem[i] <= '0;
    end else begin
        // 独立处理读写操作
        if (wr_en && !full) begin
            mem[wr_ptr] <= din;
            wr_ptr <= wr_ptr + 1'b1;
        end
        
        if (rd_en && !empty) begin
            dout <= mem[rd_ptr];
            rd_ptr <= rd_ptr + 1'b1;
        end
        
        // 更新计数器
        case ({wr_en, rd_en})
            2'b00: cnt <= cnt;           // 无操作
            2'b01: cnt <= cnt - 1'b1;    // 读操作
            2'b10: cnt <= cnt + 1'b1;    // 写操作
            2'b11: cnt <= cnt;           // 同时读写，计数器不变
        endcase
    end
end

assign full  = (cnt == DEPTH);
always @(*) begin
    if(cnt == '0) empty = 1'b1;
    else empty = 1'b0;
end

endmodule    